<template>
    <div>
        <div v-if="mode === 'DESIGN'">
            <!--组件在设计器中的样子-->
            <el-input v-model="_value" :placeholder="$t(placeholder)" @keyup.enter.native="show" disabled>
                <template #append>
                    <el-button @click="show">{{ $t('module.select') }}</el-button>
                </template>
            </el-input>
        </div>
        <div v-else-if="mode === 'PC' && !readonly">
            <!--组件在PC端预览及真实显示的样子-->
            <el-input v-model="_value" :placeholder="$t(placeholder)" @keyup.enter.native="show">
                <template #append>
                    <el-button @click="show">{{ $t('module.select') }}</el-button>
                </template>
            </el-input>
        </div>
        <div v-else-if="mode === 'MOBILE' && !readonly">
            <!--组件在移动端预览及真实显示的样子-->
            <el-input v-model="_value" :placeholder="$t(placeholder)" @keyup.enter.native="show">
                <template #append>
                    <el-button @click="show">{{ $t('module.select') }}</el-button>
                </template>
            </el-input>
        </div>
        <div v-else>
            <!--组件在流程实例预览中，只读状态下样子-->
            <el-input v-model="_value" :placeholder="$t(placeholder)" :disabled="readonly" @keyup.enter.native="show">
                <template #append>
                    <el-button @click="show" :disabled="readonly">{{ $t('module.select') }}</el-button>
                </template>
            </el-input>
        </div>
        <!-- 弹框选择数据 -->
        <w-dialog :title="$t('module.select')" width="70%" style="height:600px;max-height:950px;overflow:hidden;"
            v-model="visible" @ok="httpOk" show-cancel-button>
            <div class="dialog">
                <el-input v-model="keywordSelect" style="width: 100%;margin-bottom: 5px;"
                    :placeholder="$t('module.keywordSearch')" @change="search" />
                <el-table v-if="isMultiple == '是'" :data="tableData" style="height: 90%;width: 100%" border
                    :header-cell-style="{ color: '#000', fontWeight: 'bold' }" :cell-style="{ whiteSpace: 'pre-wrap' }"
                    @selection-change="handleSelectionChange" :row-key="getRowKey" ref="multipleTable">
                    <!-- 表格头循环 -->
                    <!-- @row-dblclick="rowClick" -->
                    <el-table-column type="selection" width="55" v-if="isMultiple == '是'"
                        :reserve-selection="true"></el-table-column>
                    <!-- 按照接口返回的key渲染 -->
                    <template v-for="(item, index) in headerDate">
                        <el-table-column v-if="item.placeholder" :prop="item.value" :key="index"
                            :label="$t(item.placeholder)" width="auto"></el-table-column>
                    </template>
                </el-table>
                <el-table v-else :data="tableData" style="height: 90%;width: 100%" border v-loading="loading"
                    :header-cell-style="{ color: '#000', fontWeight: 'bold' }" :cell-style="{ whiteSpace: 'pre-wrap' }"
                    @current-change="handleSelectionChange2" highlight-current-row>
                    <!-- 表格头循环 -->
                    <!-- 按照接口返回的key渲染 -->
                    <template v-for="(item, index) in headerDate">
                        <el-table-column v-if="item.placeholder" :key="index" :prop="item.value"
                            :label="$t(item.placeholder)" width="auto"></el-table-column>
                    </template>
                </el-table>
                <div class="demo-pagination-block" style="margin-top:10px">
                    <el-pagination :currentPage="currentPage" :page-size="pageSize" :page-sizes="[20, 50, 80, 120, 200]"
                        :small="small" :disabled="disabled" :background="background" pager-count="4"
                        layout="total, sizes, prev, pager, next, jumper" :total="total" @size-change="handleSizeChange"
                        @current-change="handleCurrentChange" />
                </div>
            </div>
        </w-dialog>
    </div>
</template>

<script>
//混入配置
import componentMinxins from '../ComponentMinxins'
export default {
    mixins: [componentMinxins],
    name: "TextSelector",
    components: {},
    emits: ['data-selected'],
    props: {
        index: {
            type: Number,
            default: 0,
        },
        modelValue: {
            type: String,
        },
        placeholder: {
            type: String,
            default: 'webAuto.selectOption',
        },
        expanding: {
            type: Boolean,
            default: false,
        },
        dataSource: {
            type: String,
            default: '',
        },
        isMultiple: {
            type: String,
            default: '是',
        },
        tables: {
            type: String,
            default: ''
        },
        rowLayoutOpen: {
            type: Number,
            default: 1,
        },
        optionText: {
            type: Array,
            default: () => {
                return []
            }
        },
        formData: {
            type: Object,
            default: () => {
                return {}
            }
        },
        http: {
            type: Object,
            default: () => {
                return {
                    url: null,
                    method: 'GET',
                    headers: [],
                    contentType: 'JSON',
                    params: [],
                    data: null,
                    preHandler: null,
                    aftHandler: {
                        isJs: false,
                        js: '',
                        rule: {
                            source: '',
                            name: '',
                            value: ''
                        }
                    },
                }
            }
        },
    },
    data() {
        return {
            loading: false,
            visible: false,
            keywordSelect: '',
            headerDate: [],
            tableData: [], // 表格绑定数据
            pageSize: 15, // 分页的
            total: 0,
            currentPage: 1,
            rowLis: [], // 选择行的数据
            small: false,
            background: false,
            preHandlerFuc: null,
            aftHandlerFuc: null,
            disabled: false,
            lineNo: '',
        }
    },
    computed: {
        _value: {
            get() {
                return this.modelValue
            },
            set(val) {
                this.$emit('update:modelValue', val)
            },
        },
        formItems() {
            return this.$store.state.design.formItems
        },
        formMap() {
            const map = new Map();
            this.itemToMap(this.formItems, map)
            return map
        },
    },
    mounted() {
        // 回显已选中的行
        this.$nextTick(() => {
            this.rowLis.forEach(row => {
                this.$refs.multipleTable.toggleRowSelection(row, true);
            });
        });
    },
    methods: {
        // 打开弹框
        show() {
            this.doRequest()
            this.visible = true
        },
        itemToMap(forms, map) {
            forms?.forEach(item => {
                if (item.name === 'TableList') {
                    map.set(item.id, item)
                    this.itemToMap(item.props.columns, map)
                } else if (item.name === 'SpanLayout') {
                    this.itemToMap(item.props.items, map)
                } else {
                    map.set(item.id, item)
                }
            })
        },
        // 多选
        handleSelectionChange(val) {
            this.rowLis = val.filter((item, index, self) =>
                index === self.findIndex(t => t.RowSelectId === item.RowSelectId)
            );
            // 同步更新 tableData 中每一行的 selection 状态
            this.tableData = this.tableData.map(row => ({
                ...row,
                selection: val.some(selectedRow => selectedRow.RowSelectId === row.RowSelectId)
            }));
        },
        // 单选
        handleSelectionChange2(val) {
            this.rowLis = [val]
        },
        getRowKey(row) {
            return row.RowSelectId; // 假设每行数据都有唯一的id字段
        },
        // 弹框点击确认
        httpOk() {
            if (!this.rowLis.length) {
                this.$message.warning(this.$t('webAuto.selectDataFirst'))
                return
            }
            let arr = []
            // 绑定对象不在表格内赋值
            this.rowLis.forEach((item, index) => {
                let objName = {} //绑定在表格中的值组合为对象
                this.optionText.forEach(a => {
                    if (Object.keys(this.formData).indexOf(a.name) != -1 && Object.keys(item).indexOf(a.value) != -1) {
                        if (this.formData[a.name] && this.formData[a.name].indexOf(item[a.value]) == -1 && this.isMultiple == '是') {
                            this.formData[a.name] = this.formData[a.name] + ',' + item[a.value]
                        } else {
                            this.formData[a.name] = item[a.value]
                        }
                    }
                    if (a.name != '') {
                        objName[a.name] = item[a.value]
                    }
                })
                let a = this.containsObject(arr, objName)
                if (!a) {
                    arr.push(objName)
                }
                // arr.push(objName)
            })
            //处理表格小数位赋值
            arr.forEach((item, index) => {
                for (const a of Object.keys(item)) {
                    if (this.formMap.length && !this.formMap?.get(a)) {
                        this.$message.warning(this.$t('webAuto.Binding') + ":" + a + this.$t('webAuto.notExist'))
                        arr = []
                        break
                    } else if (this.formMap.length && this.formMap.get(a).name && this.formMap.get(a).props?.precision) {
                        item[a] = Number(item[a]).toFixed(this.formMap.get(a).props?.precision)
                    }
                }
                if (this.tables) {
                    item.tableId = item.tableId || index + 1
                }
            })
            // 不是弹框打开表格执行下面的逻辑，一样也返回
            if (this.rowLayoutOpen != 3) {
                if (this.isMultiple == '是') {
                    this.formData[this.tables] = [...arr]
                } else if (this.tables) {
                    // 给表格id赋值
                    arr[0].tableId = Number(this.index)
                    // 判断表格是否存在数据，没有则追加，有则赋值(弹框模式)
                    if ((this.formData[this.tables]?.length || 0) - 1 <= 0) {
                        if (this.formData[this.tables]?.length) {
                            this.formData[this.tables][this.formData[this.tables]?.length - 1] = { ...this.formData[this.tables][this.formData[this.tables]?.length - 1], ...arr[0] }
                        }
                    } else {
                        // 通过index来判断是哪个点的是表格的第几行，然后取选择的行数据进行赋值
                        if (this.index && this.formData[this.tables].length > 0) {
                            this.formData[this.tables][this.index - 1] = { ...this.formData[this.tables][this.index - 1], ...arr[0] }
                        } else {
                            this.formData[this.tables][this.formData[this.tables]?.length - 1] = { ...this.formData[this.tables][this.formData[this.tables]?.length - 1], ...arr[0] }
                        }
                    }
                }
            }
            else {
                // console.log('arr[0]',arr[0],this.getMaxTableId())
                arr[0].tableId = Math.max(...(this.formData[this.tables]?.filter(x => x?.tableId !== undefined && x?.tableId !== NaN).map(x => x?.tableId) || [1]))
            }
            this.$emit('data-selected', arr[0] || {})
            // 关闭弹框
            // console.log('arr[0]', arr[0])
            // console.log(' this.formData[this.tables]', this.formData[this.tables])
            this.visible = false
        },
        // 查找存在的tableId 最大值 使用的时候永远最大值加1
        getMaxTableId() {
            const ids = []
            if (this.formData[this.tables]) {
                ids = this.formData[this.tables]?.filter(x => x?.tableId !== undefined).map(x => x?.tableId) || [1];
            }
            return ids.length ? Math.max(...ids) + 1 : 1;
        },
        // 判断数组中包含某个不确定的对象
        containsObject(array, object) {
            return array.some(item => {
                for (let key in object) {
                    if (item[key] !== object[key]) {
                        return false;
                    }
                }
                return true;
            });
        },
        // id标识长度5位
        generateUniqueId(length = 5) {
            const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
            let result = '';
            const charactersLength = characters.length;
            for (let i = 0; i < length; i++) {
                result += characters.charAt(Math.floor(Math.random() * charactersLength));
            }
            return result;
        },
        doRequest() {
            this.headerDate = []
            if (this.http.url && this.http.method) {
                const params = {
                    url: this.http.url,
                    method: this.http.method.toLowerCase(),
                    headers: {
                        'Content-Type': this.http.contentType === 'JSON' ? 'application/json' : 'application/x-www-form-urlencoded',
                        'Wflowtoken': localStorage.getItem('wflow-token'),
                        ...this.coverParams(this.http.headers || [])
                    },
                    formData: Object.assign({}, this.formData),
                    params: this.coverParams(this.http.params || []), //查询条件
                    data: this.http.contentType === 'JSON' ? JSON.parse(this.bindVar(this.http.data || '{}')) : ''
                }
                params.params.value = this.keywordSelect   //表格自定义的查询条件 关键字查询
                params.params.pageSize = this.pageSize //分页 第几页
                params.params.pageNo = this.currentPage  //分页 每页条数
                this.preHandler(params, this.http.preHandler)
                //这里由于前置处理后，可能修改params参数，所以需要重新处理
                if (this.http.contentType !== 'JSON') {
                    params.data = this.coverParams(params.params, true)
                    params.params = {} //去除参数，防止参数跑到url中
                }
                this.loading = true
                this.$axios.request(params).then(rsp => {
                    // 接口返回数据赋值给表格，自定义处理了，就没有后置处理
                    // console.log(this.options)
                    // 循环比对表格表头
                    let arr = Object.keys(rsp.data.model)
                    this.optionText.forEach(item => {
                        arr.forEach(name => {
                            if (name === item.value) {
                                this.headerDate.push(item)
                            }
                        })
                    })
                    rsp.data.data.forEach((item, index) => {
                        item.selection = false
                        item.RowSelectId = index + 1
                    })
                    this.tableData = rsp.data.data.map(item => ({
                        ...item,
                        selection: false,
                        RowSelectId: item.RowSelectId || index + 1
                    }));
                    // 回显已选中的行
                    if (this.rowLis.length) {
                        this.$nextTick(() => {
                            this.rowLis.forEach(row => {
                                this.$refs.multipleTable.toggleRowSelection(row, true);
                            });
                        });
                    }

                    this.total = rsp.data.total
                    this.loading = false
                }).catch(err => {
                    this.loading = false
                    this.$message.warning(this.$t('webAuto.RequestSource') + JSON.stringify(err))
                })
            }
        },
        //前置处理
        preHandler(params, script) {
            if (!this.preHandlerFuc) {
                this.preHandlerFuc = new Function('ctx', `${script}\n preHandler(ctx)`)
            }
            try {
                this.preHandlerFuc(params)
            } catch (e) {
                // console.log(e)
            }
        },
        bindVar(str) {
            return str.replace(/\$\{(\w+)\}/g, (match, key) => {
                console.log('bindVar', key)
                return this.formData[key] || '';
            })
        },
        //数组转对象
        coverParams(args, isForm = false) {
            let params = {};
            if (Array.isArray(args)) {
                args.forEach(arg => {
                    if (this.$isNotEmpty(arg.name)) {
                        params[arg.name] = arg.value.replace(/\$\{(\w+)\}/g, (match, key) => {
                            // 特殊处理 ${lang}
                            if (key === 'lang') {
                                return localStorage.getItem('lang')?.includes('中文') ? 'zh-CN' : localStorage.getItem('lang')?.includes('English') ? 'en-US' : 'es-MX';
                            }
                            return this.formData[key] || '';
                        })
                    }
                })
            } else {
                const properties = this.findPropertiesWithIndex(args);
                if (properties.length > 0) {
                    properties.forEach(v => {
                        let a = args[v].split('[index]')[0].split('${')[1]
                        let b = args[v].split('[index]')[1].split('.')[1].split('}')[0]
                        args[v] = this.formData[a][this.index - 1][b]
                    })
                }
                params = { ...args }
            }
            if (isForm) {
                return Object.keys(params).map(v => `${encodeURIComponent(v)}=${encodeURIComponent(params[v])}`).join('&')
            }
            return params
        },
        findPropertiesWithIndex(obj) {
            const result = [];
            for (const [key, value] of Object.entries(obj)) {
                if (typeof value === 'string' && value.includes('[index]')) {
                    result.push(key);
                }
            }
            return result;
        },

        // 弹框里面表格的查询
        search() {
            this.doRequest()
        },
        // 分页相关函数
        handleSizeChange(val) {
            this.pageSize = val
            this.doRequest()
        },
        handleCurrentChange(val) {
            this.currentPage = val
            this.doRequest()
        }
    }

}
</script>

<style scoped>
.demo-pagination-block {
    height: 40px;
    width: 100%;
    margin-top: 8px;
    box-sizing: border-box;
    font-size: 12px;
    background-color: #faf8f8;
    overflow: hidden;
}

.dialog {
    height: 100%;
    width: 100%;
    display: flex;
    flex-direction: column;
    overflow: hidden;
    height: 500px;
}

.el-select .el-select--default {
    width: 100px !important;
}

::v-deep .el-table__body tr.current-row>td {
    color: #fff;
    background: #e69346 !important;
}
</style>